package com.lineengine.lineengine.result;

import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.annotation.JsonAlias;
import com.lineengine.lineengine.common.ErrorType;
import com.lineengine.lineengine.common.CommonErrorCode;
import com.lineengine.lineengine.common.IErrorCode;
import org.slf4j.MDC;

/**
 * @author ycd0075
 * @date 2023-03-23 10:20
 */
public class DefaultResponse<T> {
    private final String traceId = MDC.get("");
    private ErrorType errorType;
    /**
     * 错误详情，可以是 json 字符串，也可以其他详情描述
     */
    private String errorDetail;
    private boolean success;
    private String code;
    @JsonAlias({"message", "msg", "errorMsg", "errorMessage"})
    private String message;
    private T data;

    public DefaultResponse() {
    }

    public DefaultResponse(ErrorType errorType, IErrorCode errorCode) {
        this(errorType, errorCode.getCode(), errorCode.getMessage());
    }

    public DefaultResponse(ErrorType errorType, IErrorCode errorCode, Object[] messageArgs) {
        this(errorType, errorCode.getCode(), errorCode.getMessage(messageArgs));
    }

//    public DefaultResponse(ErrorType errorType, String code) {
//        this(errorType, code, I18nUtils.get(code));
//    }
//
//    public DefaultResponse(ErrorType errorType, String code, Object[] messageArgs) {
//        this(errorType, code, I18nUtils.get(code, messageArgs));
//    }

    private DefaultResponse(ErrorType errorType, String code, String message) {
        this(errorType, code, message, "");
    }

    private DefaultResponse(ErrorType errorType, String code, String message, String errorDetail) {
        this.errorType = errorType;
        this.success = errorType == ErrorType.NONE;
        this.code = code;
        this.message = message;
        this.errorDetail = errorDetail;
    }

    public static <T> DefaultResponse<T> success() {
        return of(null);
    }

//    public static <T> DefaultResponse<T> of(T data, String code) {
//        DefaultResponse<T> response = new DefaultResponse<>(ErrorType.NONE, code);
//        response.setData(data);
//        return response;
//    }

    public static <T> DefaultResponse<T> of(T data) {
        DefaultResponse<T> response = new DefaultResponse<T>(ErrorType.NONE, CommonErrorCode.SUCCESS);
        response.setData(data);
        return response;
    }

//    public static <T> DefaultResponse<T> serverFail(IErrorCode errorCode) {
//        return from(ErrorType.SERVER, errorCode);
//    }
//
//    public static <T> DefaultResponse<T> serverFail(IErrorCode errorCode, Object... messageArgs) {
//        return from(ErrorType.SERVER, errorCode, messageArgs);
//    }
//
//    public static <T> DefaultResponse<T> serverFail(String code) {
//        return from(ErrorType.SERVER, code);
//    }
//
//    public static <T> DefaultResponse<T> serverFail(String code, Object... messageArgs) {
//        return from(ErrorType.SERVER, code, messageArgs);
//    }
//
//    public static <T> DefaultResponse<T> clientFail(IErrorCode errorCode) {
//        return from(ErrorType.CLIENT, errorCode);
//    }
//
//    public static <T> DefaultResponse<T> clientFail(IErrorCode errorCode, Object... messageArgs) {
//        return from(ErrorType.CLIENT, errorCode, messageArgs);
//    }
//
//    public static <T> DefaultResponse<T> clientFail(String code) {
//        return from(ErrorType.CLIENT, code);
//    }
//
//    public static <T> DefaultResponse<T> clientFail(String code, Object... messageArgs) {
//        return from(ErrorType.CLIENT, code, messageArgs);
//    }
//
//    public static <T> DefaultResponse<T> from(ErrorType errorType, IErrorCode errorCode, Object... messageArgs) {
//        return new DefaultResponse<>(errorType, errorCode, messageArgs);
//    }
//
//    public static <T> DefaultResponse<T> from(ErrorType errorType, String code, Object... messageArgs) {
//        return new DefaultResponse<>(errorType, code, messageArgs);
//    }

    public static <T> DefaultResponse<T> from(ErrorType errorType, String code, String message) {
        return new DefaultResponse<>(errorType, code, message);
    }

    public static <T> DefaultResponse<T> from(DefaultResponse<?> response) {
        return new DefaultResponse<>(response.getErrorType(),
                response.getCode(),
                response.getMessage(),
                response.getErrorDetail());
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public ErrorType getErrorType() {
        return errorType;
    }

    public void setErrorType(ErrorType errorType) {
        this.errorType = errorType;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public String getErrorDetail() {
        return errorDetail;
    }

    public void setErrorDetail(Object errorDetail) {
        if (errorDetail instanceof String) {
            this.errorDetail = (String) errorDetail;
        } else {
            this.errorDetail = JSONUtil.toJsonStr(errorDetail);
        }
    }

    public String getTraceId() {
        return traceId;
    }
}

